/*
 * Model3D.cpp
 *
 *  Created on: 22/10/2011
 *      Author: faust
 */

#include "SampleUtils.h"
#include "Model3D.h"
#include "UtilsJNI.h"

#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>

using namespace std;



Model3D::Model3D()
{

}


Model3D::~Model3D()
{
    if (vertices != 0)
        delete[]vertices;

    if (texCoords != 0)
        delete[]texCoords;

    if (vertexNormals != 0)
        delete[]vertexNormals;

    if (groups != 0)
        delete[]groups;
}

Model3D* Model3D::create(JNIEnv* env, jobject model3DObject)
{
	LOG("NDK - Model3D::create - load Model");

	Model3D* model = new Model3D();

	model->vertices = UtilsJNI::getJavaFloatArray(env, model3DObject, "getVertices", "Model3D::create");

	model->texCoords = UtilsJNI::getJavaFloatArray(env, model3DObject, "getTexCoords", "Model3D::create");

	model->vertexNormals = UtilsJNI::getJavaFloatArray(env, model3DObject, "getVertexNormals", "Model3D::create");

	model->colors = UtilsJNI::getJavaFloatArray(env, model3DObject, "getColors", "Model3D::create");


	//Load mesh groups
	Model3D::loadGroups(env, model3DObject, model, false);

	//Load occluder groups
	Model3D::loadGroups(env, model3DObject, model, true);


    return model;
}

//func = getGroupsCount, getMeshGroup
void Model3D::loadGroups(JNIEnv* env, jobject model3DObject, Model3D* model, bool isOccluder)
{
	LOG("Model3D::loadGroups - start loading groups");
	string getCount, getGroups;
	if (isOccluder) {
		getCount = "getOccluderGroupsCount";
		getGroups = "getOccluderGroup";
	}
	else {
		getCount = "getGroupsCount";
		getGroups = "getMeshGroup";
	}


	jclass jModelClass = env->GetObjectClass(model3DObject);

	jmethodID getGroupCountMethodID = env->GetMethodID(jModelClass,
													getCount.data(), "()I");
	if (getGroupCountMethodID == 0)
	{
		LOG("Model3D::loadGroups - Function %s not found.", getCount.data());
		return;
	}

	int groupCount = env->CallIntMethod(model3DObject, getGroupCountMethodID);
	if (!groupCount)
	{
		LOG("Model3D::loadGroups - %s returned zero.", getCount.data());
	}

	if (isOccluder) {
		model->occluderCount = groupCount;
		model->occluderGroups = new MeshGroup*[groupCount];
	}
	else {
		model->meshGroupCount = groupCount;
		model->groups = new MeshGroup*[groupCount];
	}


	jmethodID getGroupMethodID = env->GetMethodID(jModelClass,
		getGroups.data(), "(I)Lcom/Utils3D/MeshGroup;");

	if (getGroupMethodID == 0)
	{
		LOG("Model3D::loadGroups - Function %s not found.", getGroups.data());
		return;
	}

	// Register the mesh groups
	for (int i = 0; i < groupCount; ++i)
	{

		jobject groupObject = env->CallObjectMethod(model3DObject, getGroupMethodID, i);
		if (groupObject == NULL)
		{
			LOG("Model3D::loadGroups - GetMeshGroup() returned zero pointer");
			return;
		}

		if (isOccluder) model->occluderGroups[i] = MeshGroup::create(env, groupObject);
		else model->groups[i] = MeshGroup::create(env, groupObject);

	}
	return;
}

